#include "base/log_util.hpp"

#include <cassert>
#include <cstdio>
#include <cstring>
#include <ctime>

namespace ibox::base {

thread_local char t_time[64];
thread_local int t_timezone = -1;
thread_local struct std::tm t_tm;
thread_local struct std::tm t_gmtm;
thread_local time_t t_lastsecond;
thread_local char t_errnobuf[512];

const char *get_current_datetime() {
    time_t timer = time(nullptr);

    if (t_lastsecond != timer) {
        t_lastsecond = timer;
        ::localtime_r(&timer, &t_tm);
    }
    // to subtract gmtime and localtime for obtain timezone
    if (t_timezone == -1) {
        time_t gm_time = std::mktime(::gmtime_r(&timer, &t_gmtm));
        t_timezone = static_cast<int>(timer - gm_time) / 3600;
    }
    [[maybe_unused]] int len
        = std::snprintf(t_time,
                        sizeof(t_time),
                        "%4d-%02d-%02d %02d:%02d:%02d +%02d",
                        t_tm.tm_year + 1900,
                        t_tm.tm_mon + 1,
                        t_tm.tm_mday,
                        t_tm.tm_hour,
                        t_tm.tm_min,
                        t_tm.tm_sec,
                        t_timezone);
    assert(len == 23);
    return t_time;
}

const char *get_error_info(int error_code) {
    [[maybe_unused]] auto *p
        = ::strerror_r(error_code, t_errnobuf, sizeof(t_errnobuf));
    return t_errnobuf;
}
} // namespace ibox::base
